#include "stdafx.h"
#include "TextureManager.h"
#include "gl\GL.h"    

CTextureManager  gTextureManager;


CTextureManager::CTextureManager(void)
{
	m_updateOGL = false;
}


CTextureManager::~CTextureManager(void)
{
	std::list<CTexture*>::iterator it = m_textures.begin();
	for (; it != m_textures.end(); ++it)
	{
		delete (*it);
	}
}


CTexture* CTextureManager::FindTexture(CString URI)
{
	TRACE("CTextureManager::FindTexture");

	std::list<CTexture*>::iterator it = m_textures.begin();
	for (; it != m_textures.end(); ++it)
	{
		if (URI == (*it)->m_URI)
			return *it;
	}
	return NULL;
}


CTexture* CTextureManager::AddTexture(CString URI)
{
	TRACE("CTextureManager::AddTexture");

	CTexture *texture = FindTexture(URI); 
	if (texture == NULL)
	{
		texture = new CTexture;
		texture->m_URI = URI;
		texture->m_OpenglId = 0;
		texture->m_changed = true;
		texture->m_loadedOGL = false;
		m_updateOGL = true;
		m_textures.push_back(texture);
	}
	return texture;
}


bool CTextureManager::DelTexture(CTexture *texture)
{
	TRACE("CTextureManager::DelTexture");
	m_textures.remove(texture);

	// To do (delete data)
	if (texture->m_URI)
		delete[] texture->m_URI;

	delete texture;
	return true;
}

void CTextureManager::ModTexture(CTexture* texture, CString URI)
{
	TRACE("CTextureManager::ModTexture");

	texture->m_URI = URI;
	texture->m_changed = true;
	m_updateOGL = true;
}

unsigned int CTextureManager::GetTextureId(CString URI)
{
	CTexture *tex = FindTexture(URI);
	if (tex)
		return tex->m_OpenglId;
	else
		return 0;
}

void CTexture::OpenTextureData(int *width, int *height, int *form, BYTE **data)
{
	TRACE("CTexture::OpenTextureData");

	*width = 0;
	*height = 0;
	*form = 0;
	*data = NULL;

	// Open image via http connection
	if (m_URI.Left(7) == "http://" || m_URI.Left(7) == "HTTP://" || m_URI.Left(7) == "Http://")
	{
		CInternetSession *session = new CInternetSession();

		CStdioFile *file = session->OpenURL(m_URI.GetBuffer(), 1, INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD);	

		// read file into predefined buffer 
		BYTE *buf = new BYTE[500000];
		int n = 0, i = 0;
		while (n = file->Read(&buf[i], 500000 - i))
		{
			i += n;
			if (i == 500000)
			{
				while (i += file->Read(&buf[0], 500000));
				break;
			}
		}
		
		// read file if predefined buffer is to small
		if (i > 500000)
		{
			delete[] buf;
			buf = new BYTE[i];
			file->SeekToBegin();
			n = 0; 
			int j = 0;
			while (n = file->Read(&buf[j], i))
			{
				j += n;
			}
		}

		FIMEMORY *mem =  FreeImage_OpenMemory(buf, i);

		if (m_URI.Right(4) == "jpeg" || m_URI.Right(3) == "jpg" || m_URI.Right(3) == "JPG" || m_URI.Right(3) == "Jpg")
			m_image = FreeImage_LoadFromMemory(FIF_JPEG, mem);
		else if (m_URI.Right(3) == "png" || m_URI.Right(3) == "PNG" || m_URI.Right(3) == "Png")
			m_image = FreeImage_LoadFromMemory(FIF_PNG, mem);

		file->Close();
		session->Close();
		delete session;
		delete[] buf;
	}

	// Open image from a local folder 
	else
	{
		//image format
		FREE_IMAGE_FORMAT format;

		//check the file signature and deduce its format
		format = FreeImage_GetFileType(m_URI.GetBuffer(), 0);

		//if unknown, try to guess the file format from the file extension
		if (format == FIF_UNKNOWN) 
			format = FreeImage_GetFIFFromFilename(m_URI.GetBuffer());

		//check that the plugin has reading capabilities and load the file
		if (format != FIF_UNKNOWN && FreeImage_FIFSupportsReading(format))
			m_image = FreeImage_Load(format, m_URI.GetBuffer());
	}

	if (m_image != NULL)
	{
		//retrieve the image data
		//get the image width and height
		*width = FreeImage_GetWidth(m_image);
		*height = FreeImage_GetHeight(m_image);
		*data = FreeImage_GetBits(m_image);
		if (FreeImage_GetRedMask(m_image) & 1)
			*form = GL_RGB;
		else
			*form = GL_BGR_EXT;

		//Free FreeImage's copy of the data
//		FreeImage_Unload(image);
	}
}


void CTexture::CloseTextureData() 
{
	TRACE("CTexture::CloseTextureData");

	if (m_image != NULL)
		FreeImage_Unload(m_image);
	m_image = NULL;
}